package com.wiretrack.circuit;

import java.awt.Color;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;

import com.thoughtworks.xstream.XStream;

public class Configuration
{
	private static Logger log = Logger.getLogger(Configuration.class.getName());
	
	String soundcommand;
	String donemessage;
	String name;

	protected int windowWidth;
	protected int windowHeigth;

	public Rounds rounds;
	public RoundRefs roundrefs;
	
	public SoundFiles soundFiles;
	public TimerTexters timerTexters;
	
	public ScreenFlashers screenFlashers;
	public Flashers flashers;
	public String backgroundColor;

	public int nextalerttime;
	public int endofroundwarning;
	public String nextPrefix;
	public String speechcommand;
	public int roundspeakdelay;
	public int timeMultiplierInMS;

	public static Configuration getInstance(String pathToConfigFile) throws MalformedURLException, DocumentException
	{
		log.debug("Getting instance of config file: " + pathToConfigFile);

		XStream xstream = new XStream();
		xstream.alias("workout", Configuration.class);

		xstream.alias("rounds", Rounds.class);
		xstream.alias("round", Round.class);
		xstream.addImplicitCollection(Rounds.class, "rounds");

		xstream.addImplicitCollection(Sounds.class, "sounds");
		xstream.alias("sound", Sound.class);
		xstream.useAttributeFor(Sound.class, "refid");
		xstream.useAttributeFor(Sound.class, "playAt");

		xstream.alias("file", SoundFile.class);
		xstream.addImplicitCollection(SoundFiles.class, "soundFiles");
		xstream.useAttributeFor(SoundFiles.class, "root");

		xstream.alias("colors", ScreenColors.class);
		xstream.alias("screenFlash", ScreenFlash.class);
		xstream.alias("color", FlashColorRGB.class);

		xstream.addImplicitCollection(ScreenFlashers.class, "screenFlashers");

		xstream.addImplicitCollection(Flashers.class, "flashers");
		xstream.alias("flash", Flash.class);
		xstream.useAttributeFor(Flash.class, "refid");
		xstream.useAttributeFor(Flash.class, "flashAt");

		xstream.alias("roundrefs", RoundRefs.class);
		xstream.alias("ref", RoundRef.class);
		xstream.useAttributeFor(RoundRef.class, "refid");

		xstream.addImplicitCollection(RoundRefs.class, "roundrefs");

		xstream.alias("timerText", TimerText.class);
		xstream.addImplicitCollection(TimerTexters.class, "timerTexters");

		
		xstream.addImplicitCollection(Texts.class, "texts");
		xstream.alias("text", Text.class);
		xstream.useAttributeFor(Text.class, "refid");
		xstream.useAttributeFor(Text.class, "showAt");
		
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File(pathToConfigFile));

		Configuration config = (Configuration) xstream.fromXML(document.asXML());

		if ( config == null )
		{
			log.error("Error loading the config file: " + pathToConfigFile);
		}

		return config;
	}

	public ScreenFlash getScreenFlash(String id)
	{
		ScreenFlash sf = null;

		for (ScreenFlash f : screenFlashers.screenFlashers)
		{
			if ( f.id.equals(id) )
			{
				sf = f;
				return sf;
			}
		}
		return sf;
	}

	public Color getBackgroundColor()
	{
		String[] colors = backgroundColor.split(",");
		Color color = null;

		if ( colors != null && colors.length == 3 )
		{
			int red = Integer.parseInt(colors[0].trim());
			int green = Integer.parseInt(colors[1].trim());
			int blue = Integer.parseInt(colors[2].trim());

			color = new Color(red, green, blue);
		}

		return color;
	}

	public String toString()
	{
		StringBuilder buf = new StringBuilder();

		buf.append("\nTotal number of rounds: " + rounds.rounds.size());

		for (Round r : rounds.rounds)
		{
			buf.append("\n");
			buf.append(r.toString());
		}

		return buf.toString();
	}

	public Round getRound(RoundRef ref)
	{
		Round rnd = null;

		for (Round round : rounds.rounds)
		{
			if ( round.id.equals(ref.refid) )
			{
				rnd = new Round(round);
				break;
			}
		}

		if ( ref.name != null && ref.name.length() > 0 )
			rnd.name = ref.name;

		if ( ref.description != null && ref.description.length() > 0 )
			rnd.description = ref.description;

		if ( ref.speak != null && ref.speak.length() > 0 )
			rnd.speak = ref.speak;

		return rnd;
	}

	public Round getRoundAt(int zeroBasedIndex)
	{
		if ( zeroBasedIndex >= roundrefs.roundrefs.size() )
			return null;
		else
			return getRound(roundrefs.roundrefs.get(zeroBasedIndex));
	}

	public TimerText getTimerText(String refid)
	{
		TimerText tt = null;
		
		for (TimerText txt : timerTexters.timerTexters)
		{
			if(txt.id.equals(refid))
			{
				tt = txt;
				break;
			}
		}
		
		return tt;
	}
}
